// ----------------------------------------------------------------------------
/**
	File: buildingbridges.cpp
	Author: Zef RosnBrick
	Archive: Live Archive
	Problem Number: 2721
*/
// ----------------------------------------------------------------------------

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <list>
#include <map>
#include <vector>

using namespace std;

typedef pair<int, int> pt;
typedef pair<int, int> edge;
typedef list<pt> building;

#define empty(p) ((p).first == -1 && (p).second == -1)
#define diff(p, q) ((p).first != (q).first || (p).second != (q).second)

int r, c;
char grid[100][100];

pt parent[100][100];
list<building> buildings;

map<int, map<int, int> > nodes;
map<int, map<int, double> > dist;
map<int, int> rep;
int num_nodes;

int ds_find(int i)
{
	return rep[i] == i ? i : rep[i] = ds_find(rep[i]);
}

void ds_union(int i, int j)
{
	rep[ds_find(i)] = ds_find(j);
}

bool comp(const edge&a, const edge&b)
{
	return dist[a.first][a.second] < dist[b.first][b.second];
}

void mst(vector<edge> &edges)
{
	sort(edges.begin(), edges.end(), comp);

	int n = 0; for (int i = 0; i < edges.size(); i++)
		if (ds_find(edges[i].first) != ds_find(edges[i].second))
		{
			ds_union(edges[i].first, edges[i].second);
			edges[n++] = edges[i];
		}

	edges.erase(edges.begin() + n, edges.end());
}

void flood_fill(int i, int j, pt p, building& b)
{
	if (i < 0 || i >= r || j < 0 || j >= c || grid[i][j] != '#' || !empty(parent[i][j]))
		return;

	b.push_back(pt(i, j));
	parent[i][j] = p;
	for (int ii = -1; ii <= 1; ii++)
		for (int jj = -1; jj <= 1; jj++)
			if (ii != 0 || jj != 0)
				flood_fill(i + ii, j + jj, p, b);
}

int main()
{
	int caseno = 0;
	vector<edge> edges;

	while (++caseno)
	{
		if (!(cin >> r >> c) || (r == 0 && c == 0))
			return 0;

		if (caseno > 1)
			printf("\n");

		for (int i = 0; i < r; i++)
			for (int j = 0; j < c; j++)
				cin >> grid[i][j];

		buildings.clear();
		nodes.clear();
		num_nodes = 0;
		fill(parent[0], parent[100], pt(-1, -1));
		for (int i = 0; i < r; i++)
			for (int j = 0; j < c; j++)
				if (grid[i][j] == '#' && empty(parent[i][j]))
				{
					nodes[i][j] = num_nodes;
					rep[num_nodes] = num_nodes;
					num_nodes++;

					building b = building();
					flood_fill(i, j, pt(i, j), b);
					buildings.push_back(b);
				}

		dist.clear();
		edges.clear();
		for (int i = 0; i <= r; i++)
		{
			int b1 = -1, b2, loc, d;
			for (int j = 0; j < c; j++)
			{
				if (i - 1 >= 0 && grid[i - 1][j] == '#')
					b2 = nodes[parent[i - 1][j].first][parent[i - 1][j].second];
				else if (i < r && grid[i][j] == '#')
					b2 = nodes[parent[i][j].first][parent[i][j].second];
				else
					b2 = -1;

				if (b2 != -1)
				{
					if (b1 != -1 && b1 != b2 && (d = j - loc - 1) > 0)
						if (dist[b1].count(b2) == 0)
						{
							dist[b1][b2] = d;
							dist[b2][b1] = d;
							edges.push_back(edge(b1, b2));
						}
						else if (d < dist[b1][b2])
						{
							dist[b1][b2] = d;
							dist[b2][b1] = d;
						}

					b1 = b2;
					loc = j;
				}
			}
		}
		for (int j = 0; j <= c; j++)
		{
			int b1 = -1, b2, loc, d;
			for (int i = 0; i < r; i++)
			{
				if (j - 1 >= 0 && grid[i][j - 1] == '#')
					b2 = nodes[parent[i][j - 1].first][parent[i][j - 1].second];
				else if (j < c && grid[i][j] == '#')
					b2 = nodes[parent[i][j].first][parent[i][j].second];
				else
					b2 = -1;

				if (b2 != -1)
				{
					if (b1 != -1 && b1 != b2 && (d = i - loc - 1) > 0)
						if (dist[b1].count(b2) == 0)
						{
							dist[b1][b2] = d;
							dist[b2][b1] = d;
							edges.push_back(edge(b1, b2));
						}
						else if (d < dist[b1][b2])
						{
							dist[b1][b2] = d;
							dist[b2][b1] = d;
						}

					b1 = b2;
					loc = i;
				}
			}
		}

		mst(edges);

		int d = 0;
		for (int i = 0; i < num_nodes; i++)
			d += rep[i] == i;

		int l = 0;
		for (int i = 0; i < edges.size(); i++)
			l += dist[edges[i].first][edges[i].second];

		printf("City %i\n", caseno);
		if (num_nodes == 1)
			printf("No bridges are needed.\n");
		else if (edges.size() == 0)
			printf("No bridges are possible.\n");
		else
			printf("%i bridge%s of total length %i\n", (int)edges.size(), edges.size() != 1 ? "s" : "", l);

		if (d > 1)
			printf("%i disconnected groups\n", d);
	}
}
